使用 responseText 和 responseXML 属性都可以获取返回的值,如果响应数据不是有效的 XML 文档,而使用了 responseXML 属性,那么就会出现解析错误,不同的浏览器对 responseXML 属性解析错误的响应不同。
XMLHttpRequest 将响应信息解码为 Unicode 字符串,默认将响应数据的编码视为 UTF-8 ,但如果发现响应数据包含其它 Unicode 标示字节( UCS-2 或者 UCS-4 ),那么也可以正确解码其中的数据。
注意,如果服务器返回的是 XML 格式文档, responseText 属性并不处理 XML 文档中的编码声明,这时需要使用 responseXML 属性来处理。
在使用 responseXML 属性时,如果出现解析错误,那么浏览器将会做如下响应:
Opera 仅仅包含有一个 XML 声明,如下所示:
<?xml version= "1.0" ?>
Firefox 返回具有如下内容的 Document 对象:
<?xml
version= "1.0" encoding= "uft-8" ?> <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
`XML 解析错误:未组织好位置: http://localhost/employees.xml 行: 2 ,列: 2 :
<sourcetext>m <employee>m -^ </sourcetext> </parsererror>
IE 则返回更为复杂的 Document 对象,该 Document 对象具有一个名为 parseError 的对象,该对象包含有错误代码,通过该对象可以获取出错的详细信息。
属性 | 描述 |
---|---|
errorCode | 返回一个长整型错误码 |
reason | 返回包含错误原因的字符串 |
line | 返回表示错误行号的长整型 |
linepos | 返回表示错误的行位置的长整型 |
srcText | 返回包含引起错误的行的字符串 |
url | 返回指向被加载文档的 URL |
filepos | 返回错误的一个长整型的文件位置 |
如果 errorCode 属性的值为 0 ,那么就表示没有出现解析错误,此时,可以使用 IE 专用的 xml 属性将 Document 对象转换为 XML 字符串或者对 Document 对象进行操作。
注意, parseError 对象不属于 W3CDOM 标准,而是 IE 专有的。
综合不同浏览器的不同响应结果,可以使用下面的代码进行处理。
// 状态码显示返回了结果,下面处理结果
if (oXMLHttpRequest.status == 200) {
try {
var doc = oXMLHttpRequest.responseXML;
// 检查 doc 是否为 null ,如果不是 null , IE 、 FireFox 和 Opera 分别做出响应
//
if (doc) {
// IE
if (doc.parseError) {
var parseError = doc.parseError;
if (parseError.errorCode != 0) {
var err = ' 解析出现错误! \ n ';
err += 'errorCode =' + parseError.errorCode + '\n ';
err += 'filepos =' + parseError.filepos + '\n ';
err += 'line =' + parseError.line + '\n ';
err += 'linepos=' + parseError.linepos + '\n ';
err += 'reason =' + parseError.reason + '\n ';
err += 'srcText =' + parseError.srcText + '\n ';
err += 'url =' + parseError.url + '\n ';
alert(err); // IE 解析出错
return;
} else {
console.log(doc.xml);
// IE 正确解析
}
// Firefox 、 Opera
//
} else {
// Firefox
if (doc.documentElement) {
if (doc.documentElement.nodeName == 'parsererror ') {
alert(' 解析出现错误! '); // Firefox 解析出错
return;
} else {
console.log(doc);
// 其它浏览器正确解析
}
// Opera
} else {
alert(' 解析出现错误! '); // Opera 解析出错
return;
}
} // Chrome 、 Safari
//
} else {
alert(' 解析出现错误! '); // Chrome 、 Safari 解析出错
return;
}
} catch (err) {
alert(err.message);
}
}
可以看到,处理 responseXML 属性还是相当麻烦,推荐使用 responseText 属性,这是一个 XML 格式的字符串。
对于 XML 字符串和 DOM 之间的转换,目前,浏览器广泛支持 DOMParser 和 XMLSerializer 对象。
DOMParser 可以解析 XML 文本并返回一个 Document 对象。要使用 DOMParser ,先要使用不带参数的构造函数来实例化它,然后调用其 parseFromString() 方法,例如下面的代码:
var parser = new DOMParser();
var doc = parser.parseFromString(aStr, 'text / xml ');
parseFromString();
方法的语法格式如下:
parseFromString(text, contentType);
该方法的返回值是一个 Document 对象。
IE9 和其它主流浏览器都支持 DOMParser 对象,但 IE8 及以下版本不支持该对象,可以使用 MSXML 的 Document.loadXML() 进行 XML 解析。例如下面的代码是一个浏览器兼容性的做法。
if (oXMLHttpRequest.status == 200) {
try {
var str = oXMLHttpRequest.responseText;
if (window.DOMParser) {
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text / xml ');
} else {
var doc = new ActiveXObject('Microsoft.XMLDOM ');
doc.async = 'false';
doc.loadXML(str);
}
} catch (err) {
alert(err.message);
}
}
注意, XMLHttpRequest 对象也可以解析 XML 文档。可以参考 XMLHttpRequest 的 responseXML 属性。
使用 XMLSerializer 对象可将一个 XML 文档或 Node 对象序列化为一个 XML 格式的字符串。
要使用 XMLSerializer ,首先使用不带参数的构造函数实例化它,然后调用其 serializeToString() 方法。
var serializer = new XMLSerializer();
var xmlString = serializer.serializeToString(doc);
serializeToString() 方法的语法格式如下:
serializeToString(node);
参数 node 是要序列化的 XML 节点,可能是文档中的一个 Document 对象或者任何 Element 。
IE9 和其它主流浏览器都支持 XMLSerializer 对象,但 IE8 及以下版本不支持该对象。可以使用 MSXML 的 Node 对象的 xml 属性使 XML 变为字符串。例如下面的代码是一个浏览器兼容性的做法。
var doc = oXMLHttpRequest.responseXML;
if (window.XMLSerializer) {
var serializer = new XMLSerializer();
var xmlString = serializer.serializeToString(doc);
} else {
var xmlString = doc.xml;
}
在浏览器中,要创建一个 Document 对象,可以使用 DOMParser ,也可以使用 DOMImplementation , DOMImplementation 使用 document.implementation 属性返回,然后使用 DOMImplementation 对象的 createDocument() 方法就可以创建 Document 对象。
createDocument() 方法的语法格式如下:
createDocument(namespaceURI, qualifiedName, doctype)</div>
例如下面的代码创建一个新的空 Document 对象。
var oDOMImpl = document.implementation;var doc = oDOMImpl.createDocument( " ", " ", null);
再看下面的代码,这将创建一个 XHTML1.0 文档。
var oDOMImpl = document.implementation;var doc =
oDOMImpl.createDocument( "http://www.w3.org/1999/xhtml" ;, "html ",
null);
alert((new XMLSerializer()).serializeToString(doc));
一旦创建了 Document 对象,就可以使用标准的核心 DOM 方法操作文档了,例如下面的代码:
var oDOMImpl = document.implementation;
var doc = oDOMImpl.createDocument('http://lmssee.com/about/', 'book ', null); // 返回根元素,然后就可以使用前面介绍的标准 DOM 接口处理文档了
var root = doc.documentElement;
// 创建一个 p 元素节点
var oElementNode = doc.createElement('p ');
// 创建一个文本节点
var oTextNode = doc.createTextNode('JavaScript 权威指南 ');
// 追加节点
oElementNode.appendChild(oTextNode);
root.appendChild(oElementNode); // 查看内容
alert(new XMLSerializer().serializeToString(doc));
DOMImplementation.createDocument() 方法在 IE8 及以下版本浏览器上无法执行,所以考虑到浏览器兼容性问题,下面是一个兼容性做法。
var oDOMImpl = document.implementation;
if (oDOMImpl.createDocument) {
var doc = oDOMImpl.createDocument(str, 'html ', null);
} else if (window.DOMParser) {
var parser = new DOMParser();
var doc = parser.parseFromString('xmlstr ', 'text / xml ');
} else {
var doc = new ActiveXObject('Microsoft.XMLDOM ');
doc.async = 'false ';
doc.loadXML('xmlstr ');
}